/* 
 * File:   ContingencyMatrix.cpp
 * Author: Guilherme Monteiro
 * 
 */

#include "../headers/MetricsVectorTT.h"

/**
 * Constructor of ContingencyMatrixTT
 * 
 * @param userAnswers : file with the user answers
 * @param softwareOutput : file with the software answers
 */
MetricsVectorTT::MetricsVectorTT(string userAnswersPath, string softwareOutputPath) :
GenericMetricsVector(userAnswersPath, softwareOutputPath) {

    setUserAnswers(userAnswersPath);
    setSoftwareAnswers(softwareOutputPath, userAnswersPath);
    calculateMetricsVector();
}

MetricsVectorTT::MetricsVectorTT(const MetricsVectorTT& orig) : GenericMetricsVector(orig) {
}

MetricsVectorTT::~MetricsVectorTT() {
}

/**
 * Set vector of user answers.
 * The header of the file is removed before return.
 * 
 * @param uAnsPath
 */
void MetricsVectorTT::setUserAnswers(string uAnsPath) {
    Reader* reader1 = new Reader(uAnsPath);
    this->userAnswers = reader1->readCells();
}

/**
 * Set software output answers vector.
 * The header of the file is removed before return.
 * 
 * @param sOutputPath
 */
void MetricsVectorTT::setSoftwareAnswers(string sOutputPath, string uAnsPath) {
    Reader* reader = new Reader(sOutputPath);
    
    string tableIndexStr = "";
    string::iterator itUAns;
    for(itUAns = ++find(uAnsPath.begin(), uAnsPath.end(), '_'); *itUAns != '.'; itUAns++) {
        tableIndexStr += *itUAns;
    }
    
    printf("tableIndexStr: %s\n", tableIndexStr.c_str());
    
    this->softwareAnswers = reader->readTables()[atoi(tableIndexStr.c_str())];
}

/**
 * Analyze the level of acceptance
 * of the cells indicated by the
 * heuristic of table transcriber.
 * 
 * Returns the percents of false positives
 * and true positives in the total of heuristic answers.
 * 
 * @return percents
 * 
 */
void MetricsVectorTT::calculateMetricsVector() throw(CompatibilityAnswersException) {
    
//    if(this->userAnswers.size() != this->softwareAnswers.size()) {
//        throw CompatibilityAnswersException();
//    }
    
    setFN(0);
    setFP(0);
    setTN(0);
    setTP(0);
    
    vector<Cell>::iterator itUserAns;
    vector<Cell>::iterator itSoftwareAns;
    
    setNumCellsSoft(softwareAnswers.size());
    setNumCellsUser(userAnswers.size()); 
    
    vector<Cell*> userAnswersCellsExpanded;
    
    for(itUserAns = this->userAnswers.begin(); itUserAns != this->userAnswers.end(); itUserAns++) {
        int cellHeigth = (*itUserAns).rightBottom.y - (*itUserAns).leftUpper.y;
        int cellWidth = (*itUserAns).rightBottom.x - (*itUserAns).leftUpper.x;

        CvPoint newLU, newRB;
        newLU.x = (*itUserAns).leftUpper.x - 0.1 * cellWidth;    
        newLU.y = (*itUserAns).leftUpper.y - 0.1 * cellHeigth;
        newRB.x = (*itUserAns).rightBottom.x + 0.1 * cellWidth;
        newRB.y = (*itUserAns).rightBottom.y + 0.1 * cellHeigth;
        
        if(newLU.x < 0) {
            newLU.x = 0;
        }
        if(newLU.y < 0) {
            newLU.y = 0;
        }
        
        userAnswersCellsExpanded.push_back(new Cell(newLU, newRB));
    }
    
    vector<Cell*>::iterator itUserCellsExpanded;
    bool flag = false;
    for(itSoftwareAns = this->softwareAnswers.begin();
            itSoftwareAns != this->softwareAnswers.end(); 
            itSoftwareAns++) {
        
        for(itUserCellsExpanded = userAnswersCellsExpanded.begin(); 
                itUserCellsExpanded != userAnswersCellsExpanded.end(); 
                itUserCellsExpanded++) {
            
            if((*itUserCellsExpanded)->contains(&(*itSoftwareAns))) {
                TP++;
                flag = true;
                break;
            }
        }
        if(flag == false) {
            FP++;
        }
        flag = false;
    }
    
    
}